﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace System.Web.Mvc.Html
{
	public class HtmlTableColumnBuilder<T> : IList<HtmlTableColumn<T>>
	{
		private readonly List<HtmlTableColumn<T>> _columns = new List<HtmlTableColumn<T>>();

		public HtmlTableColumn<T> For(Expression<Func<T, object>> propertySelector)
		{
			var column = new HtmlTableColumn<T>();

			column.ColumnValueFunction = propertySelector.Compile();

			var property = propertySelector.Body as MemberExpression;
			if (property != null)
			{
				column.Name = property.Member.Name;
				column.DisplayName = property.Member.Name;
				column.Type = property.Type;
			}

			Add(column);
			
			return column;
		}

		#region IList<T>

		public int IndexOf(HtmlTableColumn<T> item)
		{
			return _columns.IndexOf(item);
		}

		public void Insert(int index, HtmlTableColumn<T> item)
		{
			_columns.Insert(index, item);
		}

		public void RemoveAt(int index)
		{
			_columns.RemoveAt(index);
		}

		public HtmlTableColumn<T> this[int index]
		{
			get
			{
				return _columns[index];
			}
			set
			{
				_columns[index] = value;
			}
		}

		public void Add(HtmlTableColumn<T> item)
		{
			_columns.Add(item);
		}

		public void Clear()
		{
			_columns.Clear();
		}

		public bool Contains(HtmlTableColumn<T> item)
		{
			return _columns.Contains(item);
		}

		public void CopyTo(HtmlTableColumn<T>[] array, int arrayIndex)
		{
			_columns.CopyTo(array, arrayIndex);
		}

		public int Count
		{
			get { return _columns.Count; }
		}

		public bool IsReadOnly
		{
			get { return false; }
		}

		public bool Remove(HtmlTableColumn<T> item)
		{
			return _columns.Remove(item);
		}

		public IEnumerator<HtmlTableColumn<T>> GetEnumerator()
		{
			return _columns.GetEnumerator();
		}

		Collections.IEnumerator Collections.IEnumerable.GetEnumerator()
		{
			return _columns.GetEnumerator();
		}

		#endregion
	}

	public static class HtmlTableColumnBuilderHelpers
	{
		public static HtmlTableColumn<T> WithDisplayName<T>(this HtmlTableColumn<T> column, string displayName)
		{
			column.DisplayName = displayName;
			return column;
		}
	}

	public class HtmlTableColumn<T>
	{
		public string Name { get; set; }

		public Type Type { get; set; }

		public string DisplayName { get; set; }

		public Func<T, object> ColumnValueFunction { get; set; }
	}
}
